using System;

namespace MessagingWPF.Infrastructure
{
	/// <summary>
	/// A subscription manager.
	/// </summary>
	public interface ISubscriptionManager
	{
		/// <summary>
		/// Subscribes the specified subscriber type for messages.
		/// </summary>
		/// <param name="subscriberType">Type of the subscriber.</param>
		/// <exception cref="ArgumentNullException">
		/// Thrown when <paramref name="subscriberType"/> is <c>null</c>.
		/// </exception>
		/// <remarks>This operation is idempotent.</remarks>
		void Subscribe(Type subscriberType);

		/// <summary>
		/// Subscribes the specified subscriber for the specified message type.
		/// </summary>
		/// <typeparam name="TMessage">The type of the message.</typeparam>
		/// <param name="subscriber">The subscriber.</param>
		/// <exception cref="ArgumentNullException">
		/// Thrown when <paramref name="subscriber"/> is <c>null</c>.
		/// </exception>
		/// <remarks>This operation is idempotent.</remarks>
		void Subscribe<TMessage>(ISubscriber<TMessage> subscriber);

		/// <summary>
		/// Subscribes the specified subscriber for all implemented subscription types.
		/// </summary>
		/// <param name="subscriber">The subscriber.</param>
		/// <exception cref="ArgumentNullException">
		/// Thrown when <paramref name="subscriber"/> is <c>null</c>.
		/// </exception>
		/// <remarks>This operation is idempotent.</remarks>
		void Subscribe(object subscriber);

		/// <summary>
		/// Unsubscribes the specified subscriber type from messages.
		/// </summary>
		/// <param name="subscriberType">Type of the subscriber.</param>
		/// <exception cref="ArgumentNullException">
		/// Thrown when <paramref name="subscriberType"/> is <c>null</c>.
		/// </exception>
		/// <remarks>This operation is idempotent.</remarks>
		void Unsubscribe(Type subscriberType);

		/// <summary>
		/// Unsubscribes the specified subscriber from the specified message type.
		/// </summary>
		/// <typeparam name="TMessage">The type of the message.</typeparam>
		/// <param name="subscriber">The subscriber.</param>
		/// <exception cref="ArgumentNullException">
		/// Thrown when <paramref name="subscriber"/> is <c>null</c>.
		/// </exception>
		/// <remarks>This operation is idempotent.</remarks>
		void Unsubscribe<TMessage>(ISubscriber<TMessage> subscriber);

		/// <summary>
		/// Unsubscribes the specified subscriber from all implemented subscription types.
		/// </summary>
		/// <param name="subscriber">The subscriber.</param>
		/// <exception cref="ArgumentNullException">
		/// Thrown when <paramref name="subscriber"/> is <c>null</c>.
		/// </exception>
		/// <remarks>This operation is idempotent.</remarks>
		void Unsubscribe(object subscriber);
	}
}